package cn.com.anypay.manager.miaoma.suantaiqrcode.handler;

import cn.com.anypay.manager.common.response.ApiResponse;
import cn.com.anypay.manager.service.RedirectValidationService;
import cn.com.anypay.manager.miaoma.suantaiqrcode.dto.QrCodeGatewayResponse;
import cn.com.anypay.manager.miaoma.suantaiqrcode.QrCodeTypeConstants;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;

import java.util.HashMap;
import java.util.Map;

/**
 * 二维码处理器抽象基类
 *
 * 提供通用的工具方法和默认实现
 */
@Slf4j
public abstract class AbstractQrCodeHandler implements QrCodeHandler {

    protected final ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    protected RedirectValidationService redirectValidationService;

    /**
     * 验证二维码内容是否有效
     *
     * @param content 二维码内容JSON字符串
     * @return 是否有效
     */
    protected boolean isValidContent(String content) {
        return content != null && !content.trim().isEmpty();
    }

    /**
     * 解析JSON内容
     *
     * @param content JSON字符串
     * @return JsonNode对象，解析失败返回null
     */
    protected JsonNode parseJsonContent(String content) {
        try {
            return objectMapper.readTree(content);
        } catch (Exception e) {
            log.error("Failed to parse JSON content: {}", content, e);
            return null;
        }
    }

    /**
     * 创建重定向响应
     *
     * @param url 目标URL
     * @return 重定向响应
     */
    protected ApiResponse<Object> createRedirectResponse(String url) {
        return createRedirectResponse(url, "处理成功，准备跳转");
    }

    /**
     * 创建重定向响应
     *
     * @param url 目标URL
     * @param message 响应消息
     * @return 重定向响应
     */
    protected ApiResponse<Object> createRedirectResponse(String url, String message) {
        if (url == null || url.trim().isEmpty()) {
            log.warn("Target URL is empty, returning bad request");
            return ApiResponse.fail(HttpStatus.BAD_REQUEST.value(), "目标URL为空");
        }

        // 验证URL安全性
        RedirectValidationService.ValidationResult validationResult = redirectValidationService.validateRedirectUrl(url);
        if (!validationResult.isValid()) {
            log.warn("Unsafe redirect URL rejected: {}, reason: {}", url, validationResult.getReason());
            return ApiResponse.fail(HttpStatus.BAD_REQUEST.value(), "不安全的重定向URL: " + validationResult.getReason());
        }

        log.info("Creating redirect response to URL: {}", url);
        return ApiResponse.redirect(url, message);
    }

    /**
     * 创建成功响应
     *
     * @param message 响应消息
     * @return 成功响应
     */
    protected ApiResponse<Object> createSuccessResponse(String message) {
        return ApiResponse.success(message, null);
    }

    /**
     * 创建成功响应
     *
     * @param message 响应消息
     * @param data 响应数据
     * @return 成功响应
     */
    protected ApiResponse<Object> createSuccessResponse(String message, Object data) {
        return ApiResponse.success(message, data);
    }

    /**
     * 创建错误响应
     *
     * @param status HTTP状态码
     * @param message 错误信息
     * @return 错误响应
     */
    protected ApiResponse<Object> createErrorResponse(HttpStatus status, String message) {
        log.warn("Creating error response: status={}, message={}", status, message);
        return ApiResponse.fail(status.value(), message);
    }

    /**
     * 创建网关重定向响应
     * 专为前端网关设计，包含结构化数据
     *
     * @param qrCodeId 二维码ID
     * @param qrCodeName 二维码名称
     * @param qrCodeType 二维码类型
     * @param url 重定向URL
     * @return 网关响应
     */
    protected ApiResponse<Object> createGatewayRedirectResponse(String qrCodeId, String qrCodeName, Integer qrCodeType, String url) {
        QrCodeGatewayResponse gatewayResponse = QrCodeGatewayResponse.builder()
                .qrCodeId(qrCodeId)
                .qrCodeName(qrCodeName)
                .qrCodeType(qrCodeType)
                .qrCodeTypeName(QrCodeTypeConstants.getTypeDescription(qrCodeType))
                .action(QrCodeGatewayResponse.ActionType.REDIRECT)
                .redirectUrl(url)
                .build();

        // 同时设置redirectUrl到ApiResponse中，保持兼容性
        ApiResponse<Object> response = ApiResponse.success("处理成功，准备跳转", gatewayResponse);
        response.setRedirectUrl(url);
        return response;
    }

    /**
     * 创建网关显示响应
     * 专为前端网关设计，用于显示图片、文本等内容
     *
     * @param qrCodeId 二维码ID
     * @param qrCodeName 二维码名称
     * @param qrCodeType 二维码类型
     * @param displayType 显示类型
     * @param content 显示内容
     * @param title 标题
     * @param description 描述
     * @return 网关响应
     */
    protected ApiResponse<Object> createGatewayDisplayResponse(String qrCodeId, String qrCodeName, Integer qrCodeType,
                                                               String displayType, String content, String title, String description) {
        QrCodeGatewayResponse.DisplayData displayData = QrCodeGatewayResponse.DisplayData.builder()
                .type(displayType)
                .content(content)
                .title(title)
                .description(description)
                .metadata(new HashMap<>())
                .build();

        QrCodeGatewayResponse gatewayResponse = QrCodeGatewayResponse.builder()
                .qrCodeId(qrCodeId)
                .qrCodeName(qrCodeName)
                .qrCodeType(qrCodeType)
                .qrCodeTypeName(QrCodeTypeConstants.getTypeDescription(qrCodeType))
                .action(QrCodeGatewayResponse.ActionType.DISPLAY)
                .displayData(displayData)
                .build();

        return ApiResponse.success("处理成功，准备显示内容", gatewayResponse);
    }

    /**
     * 创建网关显示响应（带元数据）
     *
     * @param qrCodeId 二维码ID
     * @param qrCodeName 二维码名称
     * @param qrCodeType 二维码类型
     * @param displayType 显示类型
     * @param content 显示内容
     * @param title 标题
     * @param description 描述
     * @param metadata 元数据
     * @return 网关响应
     */
    protected ApiResponse<Object> createGatewayDisplayResponse(String qrCodeId, String qrCodeName, Integer qrCodeType,
                                                               String displayType, String content, String title, String description,
                                                               Map<String, Object> metadata) {
        QrCodeGatewayResponse.DisplayData displayData = QrCodeGatewayResponse.DisplayData.builder()
                .type(displayType)
                .content(content)
                .title(title)
                .description(description)
                .metadata(metadata != null ? metadata : new HashMap<>())
                .build();

        QrCodeGatewayResponse gatewayResponse = QrCodeGatewayResponse.builder()
                .qrCodeId(qrCodeId)
                .qrCodeName(qrCodeName)
                .qrCodeType(qrCodeType)
                .qrCodeTypeName(QrCodeTypeConstants.getTypeDescription(qrCodeType))
                .action(QrCodeGatewayResponse.ActionType.DISPLAY)
                .displayData(displayData)
                .build();

        return ApiResponse.success("处理成功，准备显示内容", gatewayResponse);
    }

    /**
     * 记录处理开始日志
     *
     * @param id 二维码ID
     */
    protected void logHandleStart(String id) {
        log.info("[{}] Processing QR code scan, id: {}", getHandlerName(), id);
    }

    /**
     * 记录处理完成日志
     *
     * @param id 二维码ID
     * @param result 处理结果描述
     */
    protected void logHandleComplete(String id, String result) {
        log.info("[{}] QR code processing completed, id: {}, result: {}", getHandlerName(), id, result);
    }
}